package queue

import "sync"

var (
	MqttQueueB *CircularQueue
	MqttQueueN *CircularQueue
)

type CircularQueue struct {
	data   []any
	head   int
	tail   int
	size   int
	count  int // 新增元素计数器
	_mutex sync.Mutex
}

func NewCircularQueue(size int) *CircularQueue {
	if size < 1 {
		size = 1 // 确保最小容量为1
	}
	return &CircularQueue{
		data:  make([]any, size),
		size:  size,
		head:  0,
		tail:  -1, // 初始化为-1表示空队列
		count: 0,
	}
}

// IsEmpty 判断队列是否为空
func (q *CircularQueue) IsEmpty() bool {
	return q.count == 0
}

// IsFull 判断队列是否已满
func (q *CircularQueue) IsFull() bool {
	return q.count == q.size
}

// Enqueue 入队操作（自动覆盖旧数据）
func (q *CircularQueue) Enqueue(value any) {
	q._mutex.Lock()
	defer q._mutex.Unlock()

	if q.IsFull() {
		// 队列已满时，头指针向前移动
		q.head = (q.head + 1) % q.size
		q.count-- // 保持计数不超过容量
	}

	// 更新尾指针
	q.tail = (q.tail + 1) % q.size
	q.data[q.tail] = value
	q.count++
}

// Dequeue 出队操作
func (q *CircularQueue) Dequeue() (any, bool) {
	q._mutex.Lock()
	defer q._mutex.Unlock()

	if q.IsEmpty() {
		return nil, false
	}

	value := q.data[q.head]
	q.head = (q.head + 1) % q.size
	q.count--

	// 重置指针状态（可选）
	if q.IsEmpty() {
		q.head = 0
		q.tail = -1
	}

	return value, true
}

// Peek 查看队首元素（不出队）
func (q *CircularQueue) Peek() (any, bool) {
	q._mutex.Lock()
	defer q._mutex.Unlock()

	if q.IsEmpty() {
		return nil, false
	}
	return q.data[q.head], true
}

// Size 获取当前队列元素数量
func (q *CircularQueue) Size() int {
	q._mutex.Lock()
	defer q._mutex.Unlock()
	return q.count
}

// Capacity 获取队列容量
func (q *CircularQueue) Capacity() int {
	return q.size
}

// Reset 重置队列
func (q *CircularQueue) Reset() {
	q._mutex.Lock()
	defer q._mutex.Unlock()
	q.head = 0
	q.tail = -1
	q.count = 0
}
